package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"regexp"
	"strings"
	"time"
)

// 定义结构体匹配JSON数据
type ScenicSpot struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Area        string `json:"area"`
	Price       string `json:"price"`
	FreeTickets string `json:"freeTickets"`
	ServiceTime string `json:"serviceTime"`
	Link        string `json:"link"`
	Detail      *DetailInfo `json:"detail,omitempty"`
}

// 详细信息结构体
type DetailInfo struct {
// 	CardRights string `json:"card_rights"`
// 	Ticket     string `json:"ticket"`
// 	Status     string `json:"status"`
	OpenTime   string `json:"open_time"`
	Phone      string `json:"phone"`
	Address    string `json:"address"`
}

func main() {
	// 读取JSON文件
	jsonFile := "/Users/renxing/code/interesting_toolbox/coordinates_map_v2/data1.json"
	outputFile := "/Users/renxing/code/interesting_toolbox/coordinates_map_v2/data2.json"

	file, err := ioutil.ReadFile(jsonFile)
	if err != nil {
		fmt.Printf("读取文件错误: %v\n", err)
		return
	}

	// 解析JSON数据
	var scenicSpots []ScenicSpot
	err = json.Unmarshal(file, &scenicSpots)
	if err != nil {
		fmt.Printf("解析JSON错误: %v\n", err)
		return
	}

	fmt.Printf("共找到 %d 个景区数据\n\n", len(scenicSpots))

	// 创建HTTP客户端，设置超时时间
	client := &http.Client{
		Timeout: 30 * time.Second,
	}

	// 循环处理每个景区数据，提取详细信息
	for i := range scenicSpots {
		spot := &scenicSpots[i]
		fmt.Printf("处理第 %d 个景区: %s\n", i+1, spot.Name)

		// 抓取页面内容并提取详细信息
		detail, err := extractDetailInfo(client, spot.Link)
		if err != nil {
			fmt.Printf("  提取详细信息失败: %v\n", err)
			// 即使失败也继续处理下一个
			continue
		}

		spot.Detail = detail
// 		fmt.Printf("  详细信息提取成功\n")

// 		fmt.Printf("  持卡权益: %s\n", detail.CardRights)
// 		fmt.Printf("  门票信息: %s\n", detail.Ticket)
// 		fmt.Printf("  景区状态: %s\n", detail.Status)
		fmt.Printf("  开放时间: %s\n", detail.OpenTime)
		fmt.Printf("  联系电话: %s\n", detail.Phone)
		fmt.Printf("  详细地址: %s\n", detail.Address)
		fmt.Println()

		// 添加延迟，避免请求过于频繁
		time.Sleep(2 * time.Second)
	}

	// 保存更新后的JSON数据
	updatedData, err := json.MarshalIndent(scenicSpots, "", "  ")
	if err != nil {
		fmt.Printf("JSON序列化错误: %v\n", err)
		return
	}

	err = ioutil.WriteFile(outputFile, updatedData, 0644)
	if err != nil {
		fmt.Printf("写入文件错误: %v\n", err)
		return
	}

	fmt.Printf("处理完成！更新后的数据已保存到: %s\n", outputFile)
}

// 提取详细信息
func extractDetailInfo(client *http.Client, url string) (*DetailInfo, error) {
	htmlContent, err := fetchPageContent(client, url)
	if err != nil {
		return nil, err
	}

	// 提取详细信息
	detail := &DetailInfo{}

	// 使用正则表达式提取各个字段
// 	detail.CardRights = extractField(htmlContent, "持卡权益:")
// 	detail.Ticket = extractField(htmlContent, "门票信息:")
// 	detail.Status = extractField(htmlContent, "景区状态:")
	detail.OpenTime = extractField(htmlContent, "开放时间:")
	detail.Phone = extractField(htmlContent, "联系电话:")
	detail.Address = extractField(htmlContent, "详细地址:")

	return detail, nil
}

// 提取特定字段的内容
func extractField(htmlContent, fieldName string) string {
	// 构建正则表达式来匹配类似这样的模式：
	// <span>持卡权益:</span><span class=" marl20">免票1次</span>
	pattern := fmt.Sprintf(`<span[^>]*>%s</span>\s*<span[^>]*class="[^"]*marl20[^"]*"[^>]*>([^<]+)</span>`, regexp.QuoteMeta(fieldName))

	re := regexp.MustCompile(pattern)
	matches := re.FindStringSubmatch(htmlContent)

	if len(matches) > 1 {
		return strings.TrimSpace(matches[1])
	}

	// 如果上面的模式没匹配到，尝试更宽松的模式
	pattern2 := fmt.Sprintf(`%s[^<]*<[^>]*>([^<]+)</span>`, regexp.QuoteMeta(fieldName))
	re2 := regexp.MustCompile(pattern2)
	matches2 := re2.FindStringSubmatch(htmlContent)

	if len(matches2) > 1 {
		return strings.TrimSpace(matches2[1])
	}

	return "" // 如果没有找到，返回空字符串
}

// 抓取页面内容
func fetchPageContent(client *http.Client, url string) (string, error) {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return "", fmt.Errorf("创建请求失败: %v", err)
	}

	// 设置请求头，模拟浏览器访问
	req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
	req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 检查响应状态
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("HTTP错误: %s", resp.Status)
	}

	// 读取响应内容
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("读取响应失败: %v", err)
	}

	return string(body), nil
}